#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
//文件
//1.空文件，也要再磁盘上占据空间
//2.文件 = 内容 + 属性
//3.文件操作 = 对内容 + 对属性 or 对内容和属性
//4.标定一个问题，必须使用：文件路径+文件名【唯一性】
//5.如果没有指明对应的文件路径，默认实在 当前路径(进程当前的路径)进行文件访问
//6.当我们把fopen,fclose,fwrite等接口写完之后，代码编译之后，形成二进制可执行程序之后
//，但没有运行，文件对应的操作没有被执行。（对文件的操作，本质：对进程文件的操作！）
//7.一个文件要被访问，就必须鲜卑打开！
//所以，文件操作的本质：进程 和 被打开文件 的关系

//进程可以打开多个文件吗？可以 -> 系统中一定存在大量的 被打开的文件 -> 被打开的文件，也要被OS管理起来
//struct file {} -> 包含了文件的大部分属性


/////////////////////////////////////////////////////////////////////////////////////////////

//fopen   fclose  fwrite   fread   fseek  ->库函数接口(底层都是系统调用接口)
//open    close   write    read    lseek  ->系统调用接口

//标记位传参
//每一个宏对应的数值，只有一个比特位时1，彼此位置不重合（每一个比特位对应不同的返回值，因为以前C语言没有bool值）
#define ONE (1<<0)
#define TWO (1<<1)
#define THREE (1<<2)
#define FOUR (1<<3)

void show(int flags)
{
  if(flags & ONE) printf("one\n");
  if(flags & TWO) printf("two\n");
  if(flags & THREE) printf("three\n");
  if(flags & FOUR) printf("four\n");
}



//我没有指明路径
#define FILE_NAME(number) "log.txt"#number  //宏替换

int main()
{
    umask(0);//改的是子进程的掩码，不会改变系统的
    //C语言中"w"->O_WEONLY O_CREAT O_TRUNC 0666
    //C语言中"a"->O_APPEND
    //O_WRONLY:只写的方式打开
    //O_REAER:创建文件
    //O_TRUNC:清空文件信息，不然你重新写入也只是覆盖
   // int fd = open(FILE_NAME,O_WRONLY | O_CREAT | O_TRUNC,0666);//写文件默认不会自动创建文件
   
  //task_struct -> struct files_struct * files -> stuct files_struct(进程的文件描述符表) ->struct file*
  //文件描述符的本质，就是数组的下标。
   //三个标准输入输出流
   //stdin  --> 键盘  o
   //stdout --> 屏幕  1
   //stderr --> 屏幕  2
    int fdO = open(FILE_NAME(1),O_WRONLY | O_CREAT | O_APPEND,0666);// 3
    int fd1 = open(FILE_NAME(2),O_WRONLY | O_CREAT | O_APPEND,0666);// 4
    int fd2 = open(FILE_NAME(3),O_WRONLY | O_CREAT | O_APPEND,0666);// 5
    int fd3 = open(FILE_NAME(4),O_WRONLY | O_CREAT | O_APPEND,0666);// 6
    int fd4 = open(FILE_NAME(5),O_WRONLY | O_CREAT | O_APPEND,0666);
   // int fd = open(FILE_NAME,O_RDONLY);
    if(fd < 0)//-1打开失败
    {
        perror("open");
        return -1;
    }
    
    char buffer[1024];
    ssize_t num = read(fd,buffer,sizeof(buffer)-1);//buffer是缓冲区 ，sizeof(buffer)-1:给缓冲区预留一个末尾位置存入0，防止缓冲区溢出；
    if(num > 0) buffer[num] = 0; //0,'\0',NULL -> 0
    printf("%s",buffer);



    //int cnt = 5; 
    //char outBuffer[64];
    //while(cnt--)
    //{
    //    sprintf(outBuffer,"%s:%d\n","hello work",cnt);//格式化转字符串
    //    //你以\0作为字符串的结尾，是C语言的规定，和我文件又什么关系呢？        
    //   // write(fd, outBuffer, strlen(outBuffer)+1);//向文件写入string的时候，要不要+1？
    //    write(fd, outBuffer, strlen(outBuffer));

    //}
    //printf("fd:%d\n",fd);
    close(fd);







  //show(ONE);
  //printf("-------------------\n");
  //show(ONE | TWO);
  //printf("-------------------\n");
  //show(ONE | TWO | THREE);
  //printf("-------------------\n");
  //show(ONE | TWO | THREE | FOUR);
  //printf("-------------------\n");
  //以w方式单纯的打开为念，c会自动清空内部的数据
  //0666 & ~umask
//  FILE * fp = fopen(FILE_NAME,"r"); //r,w, r+(读写，不存在出错),w+(读写，不存在创建),a(append,追加)，a+()
//  if(NULL == fp)
//  {
//    perror("fopen");
//    return 1;
//  }
//  char buffer[64];
//  while(fgets(buffer,sizeof(buffer)-1,fp) != NULL)//-1是为了留一个位置给fgets疏导传到buffer时会再末尾添加\0，防止没位置
//  {
//    puts(buffer);//输出字符串到屏幕上
//  }
//  
//  // int cnt = 5;
//  // while(cnt--)
//  // {
//  //   fprintf(fp,"%s:%d\n","hello wrold",cnt);
//  // }
//  
//
//  fclose(fp);
  return 0;
}



